<template>
  <div>
    <!-- 面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>商品添加</el-breadcrumb-item>
    </el-breadcrumb>

    <!--卡片视图 -->
    <el-card>
      <!-- 提示区域 -->
      <!-- 
            center 居中
            show-icon 显示图标
            :closable关闭删除按钮 -->
      <el-alert
        title="添加商品信息"
        type="info"
        center
        show-icon
        :closable="false"
      >
      </el-alert>

      <!--步骤条区域  -->
      <!-- align-center 居中显示 
      :active="activeIndex - 0"   activeIndex - 0转为整形，
      绑定具体激活显示哪一个标签页，默认是索引0，1，2，3，4-->
      <el-steps
        :space="200"
        :active="activeIndex - 0"
        finish-status="success"
        align-center
      >
        <el-step title="基本信息"></el-step>
        <el-step title="商品参数"></el-step>
        <el-step title="商品属性"></el-step>
        <el-step title="商品图片"></el-step>
        <el-step title="商品内容"></el-step>
        <el-step title="完成"></el-step>
      </el-steps>

      <!-- tab栏区域 
      model 绑定数据对象
      rules 表单校验
      ref 表单清空的引用
      label-position 文字所在输入框的位置-->
      <el-form
        :model="this.$route.name === 'editProduct' ? editForm : addForm"
        :rules="
          this.$route.name === 'editProduct' ? editFormRules : addFormRules
        "
        :ref="this.$route.name === 'editProduct' ? 'editFormRef' : 'addFormRef'"
        label-width="100px"
        label-position="right"
      >
        <!-- tab-position 指定标签位置
      v-model 绑定显示哪个tab标签 根据name 值显示 
      一定要在<el-tabs标签之外嵌套el-form，否则不行
      before-leave 切换标签之前的钩子函数，-->
        <el-tabs
          v-model="activeIndex"
          :tab-position="'left'"
          :before-leave="beforeTabLeave"
          @tab-click="tabClicked"
        >
          <el-tab-pane label="基本信息" name="0">
            <el-form-item label="商品名称" prop="title">
              <el-input
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.title"
              ></el-input>
              <el-input v-else v-model="addForm.title"></el-input>
            </el-form-item>
            <el-form-item label="商品原价" prop="oldPrice" type="number">
              <el-input
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.oldPrice"
              ></el-input>
              <el-input v-else v-model="addForm.oldPrice"></el-input>
            </el-form-item>
            <el-form-item label="商品现价" prop="price" type="number">
              <el-input
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.price"
              ></el-input>
              <el-input v-else v-model="addForm.price"></el-input>
            </el-form-item>
             <el-form-item label="商品数量" prop="number" type="number">
              <el-input
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.number"
              ></el-input>
              <el-input v-else v-model="addForm.number"></el-input>
            </el-form-item>
            <el-form-item label="转手原因" prop="reasonsFoSale">
              <el-input
                type="textarea"
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.reasonsFoSale"
              ></el-input>
              <el-input
                v-else
                type="textarea"
                v-model="addForm.reasonsFoSale"
              ></el-input>
            </el-form-item>
            <el-form-item label="发布学校" prop="school">
              <el-input
                type="textarea"
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.school"
                placeholder="请输入完整的学校名称"
              ></el-input>
              <el-input
                v-else
                type="textarea"
                v-model="addForm.school"
                placeholder="请输入完整的学校名称"
              ></el-input>
            </el-form-item>
            <el-form-item label="商品分类" prop="categoryId">
              <!-- 选择商品分类的级联选择框 -->
              <!-- 
        expand-trigger= "hover" 当鼠标放上去自动显示子分类
       options属性指定选项数组即可渲染出一个级联选择器
       通过props.expandTrigger可以定义展开子级菜单的触发方式 
       @change选择项发生变化触发这个函数
       级联选择器中v-model的值必须为数组，不然会保错-->
              <el-cascader
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.categoryId"
                :options="catelist"
                expand-trigger="hover"
                :props="cateProps"
                @change="handleChanged"
                change-on-select
              ></el-cascader>
              <el-cascader
                v-else
                v-model="addForm.categoryId"
                :options="catelist"
                expand-trigger="hover"
                :props="cateProps"
                @change="handleChanged"
                change-on-select
              ></el-cascader>
            </el-form-item>
            <el-form-item label="推荐：" prop="orderId">
              <el-input-number
                v-if="this.$route.name === 'editProduct'"
                v-model="editForm.marker"
                :min="0"
              />
              <el-input-number v-else v-model="addForm.marker" :min="0" />
            </el-form-item>
            <el-button
              type="primary"
              style="margin-top: 12px; margin-left: 350px"
              @click="next"
              >下一步，填写商品参数</el-button
            >
          </el-tab-pane>
          <el-tab-pane label="商品参数" name="1">
            <el-form-item
              :label="item.attrName"
              v-for="item in manyTableData"
              :key="item.id"
            >
              <!-- 复选框组 -->
              <el-checkbox-group v-model="item.checkedCities">
                <!-- border 带边框 -->
                <el-checkbox
                  :label="cb"
                  v-for="(cb, i) in item.attrVals"
                  :key="i"
                  border
                ></el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-button
              plain
              type="primary"
              style="margin-top: 12px; margin-left: 270px"
              @click="step"
              >上一步,填写商品信息</el-button
            >
            <el-button type="primary" style="margin-top: 12px" @click="next"
              >下一步，填写商品属性</el-button
            >
          </el-tab-pane>
          <el-tab-pane label="商品属性" name="2">
            <el-form-item
              :label="item.attrName"
              v-for="item in onlyTableData"
              :key="item.id"
            >
              <el-input v-model="item.attrVals"></el-input>
            </el-form-item>

            <el-button
              plain
              type="primary"
              style="margin-top: 12px; margin-left: 270px"
              @click="step"
              >上一步,填写商品参数</el-button
            >
            <el-button type="primary" style="margin-top: 12px" @click="next"
              >下一步，上传商品图片</el-button
            >
          </el-tab-pane>

          <el-tab-pane label="商品图片" name="3">
            <!--action 上传图片的后台地址 
            on-preview 处理图片浏览操作
            on-remove  处理移除图片的操作
            list-type 文件列表的类型
            headers 设置上传的请求头部
            on-success 文件上传成功时的钩子
            auto-upload 是否在选取文件后立即进行上传-->
            <el-upload
              v-if="this.$route.name === 'editProduct'"
              ref="upload"
              :action="uploadURL"
              list-type="picture-card"
              :on-preview="handlePreview"
              :on-remove="handleRemove"
              :headers="headerObj"
              :on-success="handleSuccess"
              :on-error="handleError"
              :auto-upload="false"
              :file-list="editForm.productPic"
            >
              <i class="el-icon-plus"></i
            ></el-upload>
            <el-upload
              v-else
              ref="upload"
              :action="uploadURL"
              list-type="picture-card"
              :on-preview="handlePreview"
              :on-remove="handleRemove"
              :headers="headerObj"
              :on-success="handleSuccess"
              :on-error="handleError"
              :auto-upload="false"
              :file-list="addForm.productPic"
            >
              <i class="el-icon-plus"></i>
            </el-upload>
            <el-button
              style="margin-left: 10px"
              size="small"
              type="success"
              @click="submitUpload"
              >上传到服务器</el-button
            >
            <!-- 图片预览 -->
            <el-dialog
              title="图片预览"
              :visible.sync="previewVisible"
              width="50%"
            >
              <!-- previewPath 图片地址 -->
              <img :src="previewPath" alt="" class="avatar" />
            </el-dialog>

            <el-button
              plain
              type="primary"
              style="margin-top: 12px; margin-left: 270px"
              @click="step"
              >上一步,填写商品属性</el-button
            >
            <el-button type="primary" style="margin-top: 12px" @click="next"
              >下一步，填写商品内容</el-button
            >
          </el-tab-pane>
          <el-tab-pane label="商品内容" name="4">
            <!-- 富文本编辑器组件 -->
            <quill-editor
              v-if="this.$route.name === 'editProduct'"
              v-model="editForm.intro"
            >
            </quill-editor>
            <quill-editor v-else v-model="addForm.intro"> </quill-editor>
            <!-- 添加商品的按钮 -->
            <el-button
              plain
              type="primary"
              style="margin-top: 12px; margin-left: 270px"
              @click="step"
              >上一步,上传商品图片</el-button
            >

            <el-button
              v-if="this.$route.name === 'editProduct'"
              type="primary"
              class="btnAdd"
              style="margin-top: 12px"
              @click="edit"
              >修改商品</el-button
            >
            <el-button
              v-else
              type="primary"
              class="btnAdd"
              style="margin-top: 12px"
              @click="add"
              >添加商品</el-button
            >
          </el-tab-pane>
        </el-tabs>
      </el-form>
    </el-card>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  data() {
    return {
      //步骤条默认激活索引
      activeIndex: '0',
      //商品分类列表
      catelist: [],
      //级联选择框的配置对象
      cateProps: {
        value: 'id',
        label: 'categoryName',
        children: 'children',
        //商品所属的分类数组
        categoryId: [],
      },
      //添加商品表单
      addForm: {
        title: '',
        oldPrice: 0,
        price: 0,
        number: 0,
        //商品所属的分类数组
        categoryId: [],
        //商品的详情描述
        intro: '',
        //参数
        productAttr: [],
        //排序
        marker: '0',
        //图片数组
        productPic: [],
      },
      //编辑商品表单
      editForm: {
        title: '',
        oldPrice: 0,
        price: 0,
        number: 0,
        //商品所属的分类数组
        categoryId: [],
        //商品的详情描述
        intro: '',
        //参数
        productAttr: [],
        //排序
        marker: '0',
        //图片数组
        productPic: [],
      },
      //添加表单的验证规则对象
      addFormRules: {
        title: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
        oldPrice: [
          { required: true, message: '请输入商品价格', trigger: 'blur' },
        ],
        price: [{ required: true, message: '请输入商品价格', trigger: 'blur' }],
         number: [
          { required: true, message: '请输入商品数量', trigger: 'blur' },
        ],
        reasonsFoSale: [
          { required: true, message: '请输入转手原因', trigger: 'blur' },
        ],
        categoryId: [
          { required: true, message: '请选中商品分类', trigger: 'blur' },
        ],
         school: [
          { required: true, message: '请输入发布学校', trigger: 'blur' },
        ],
      },
      editFormRules: {
        title: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
        oldPrice: [
          { required: true, message: '请输入商品价格', trigger: 'blur' },
        ],
        price: [{ required: true, message: '请输入商品价格', trigger: 'blur' }],
         number: [
          { required: true, message: '请输入商品数量', trigger: 'blur' },
        ],
        reasonsFoSale: [
          { required: true, message: '请输入转手原因', trigger: 'blur' },
        ],
        categoryId: [
          { required: true, message: '请选中商品分类', trigger: 'blur' },
        ],
         school: [
          { required: true, message: '请输入发布学校', trigger: 'blur' },
        ],
      },
      //动态参数列表数据
      manyTableData: [],
      //静态属性列表数据
      onlyTableData: [],
      //上传图片的url地址
      uploadURL: 'http://8.134.34.190:8088/file/upload',
      //图片上传组件的headers请求头对象
      headerObj: {
        Authorization: window.sessionStorage.getItem('token'),
      },
      //图片的完整url
      previewPath: '',
      //图片浏览隐藏对话框
      previewVisible: false,
      //文件列表
      fileList: [],
    }
  },
  created() {
    this.getCateList()
    // 通过获取路由名称，判断进入哪个步骤editProduct编辑商品跳转过来的
  },
  mounted() {
    if (this.$route.name === 'editProduct') {
      //获取商品数据
      this.getProductList()
      this.activeIndex = '0'
      // courseId来源于路由  addProduct编辑大纲跳转过来的
    }
  },
  methods: {
    //【编辑商品】获取商品数据
    async getProductList() {
      const { data: res } = await this.$http.get(
        'api/service-product/admin/product/list',
        {
          params: {
            page: 1,
            limit: 1,
            id: this.$route.params.id,
          },
        }
      )
      // console.log(res.data)

      if (res.code !== 200) {
        return this.$message.error(res.msg)
      }

      //把数据列表赋值给catelist
      this.editForm = res.data.records[0]
      //categoryId为字符串 通过split(' ')转为数组
      this.editForm.categoryId = this.editForm.categoryId.split(' ')
      //给分类id赋值（防止因为编辑菜单导致无法选中分类项）
      this.editForm.categoryList.forEach((item) => {
        //indexOf（）返回为-1说明不存在数组中
        if (this.editForm.categoryId.indexOf(item.id) == -1) {
          //unshift从头开始添加
          this.editForm.categoryId.unshift(item.id)
        }
        // console.log(this.addForm.categoryId)
      })
      // console.log(this.editForm.categoryId)
      //给图片拼接访问url
      if (this.editForm.productPic) {
        if (this.editForm.productPic.length > 0) {
          this.editForm.productPic.forEach((item1) => {
            item1.url = 'http://8.134.34.190/' + item1.url
          })
        }
      }
      // console.log(this.editForm)
      // //绑定动态参数
      // this.manyTableData = this.editForm.attrManyList

      // console.log(this.manyTableData)

      //静态属性
      this.onlyTableData = this.editForm.attrOnlyList

      // console.log(this.editForm)
    },

    //获取所有商品分类数据
    async getCateList() {
      const { data: res } = await this.$http.get(
        'api/service-product/admin/product/category/list'
      )
      if (res.code !== 200) {
        return this.$message.error(res.msg)
      }

      //把数据列表赋值给catelist
      this.catelist = res.data.records
      // console.log(this.catelist)
    },

    //级联选择框选择项变化，回触发这个函数
    handleChanged() {
      //如果选中的不是三级分类
      if (this.addForm.categoryId) {
        if (this.addForm.categoryId.length !== 3) {
          //清空选中值
          this.addForm.categoryId = []
        }
      }
    },

    //切换标签之前的钩子函数
    //activeName 跳转的标签页名称，oldActiveName原标签页名称
    //若返回 false 或者返回 Promise 且被 reject，则阻止切换。
    beforeTabLeave(activeName, oldActiveName) {
      // console.log("即将离开的标签页名："+oldActiveName)
      // console.log("即将进入的标签页名："+activeName)
      // return false
      if (this.$route.name === 'editProduct') {
        if (oldActiveName === '0' && this.editForm.categoryId.length !== 3) {
          this.$message.error('请先选择商品分类！')
          return false
        }
        return true
      } else {
        if (oldActiveName === '0' && this.addForm.categoryId.length !== 3) {
          this.$message.error('请先选择商品分类！')
          return false
        }
        return true
      }
    },
    //tab 被选中时触发
    async tabClicked() {
      // console.log(this.activeIndex)
      //证明访问的是商品参数动态参数面板
      if (this.activeIndex === '1') {
        // console.log('动态参数面板')
        //根据所选分类的id，和当前所处的面板，获取对应的参数
        const { data: res } = await this.$http.get(
          `api/service-product/admin/product/attribute/${this.cateId}`,
          {
            params: { attrSel: 'many' },
          }
        )
        // console.log(res)

        if (res.code !== 200) {
          return this.$message.error('获取参数列表失败')
        }
        // console.log(res.data)
        //分割一下动态参数值，字符串转为数组
        res.data.forEach((item) => {
          item.attrVals = item.attrVals ? item.attrVals.split(' ') : []
        })
        //绑定动态参数
        this.manyTableData = res.data
        //必须要给选中列表checkedCities绑定一个空的数组，（不然无法正常显示其参数值）
        this.manyTableData.forEach((item) => {
          if (this.$route.name !== 'editProduct') {
            item.checkedCities.push('')
          }
        })
        //绑定选中动态参数
        if (this.$route.name === 'editProduct') {
          //分割一下动态参数值，字符串转为数组
          this.editForm.attrManyList.forEach((ManyList) => {
            ManyList.attrVals = ManyList.attrVals
              ? ManyList.attrVals.split(' ')
              : []

            //绑定动态参数，（修改商品的参数信息时，显示全部参数，拥有的参数显示已选中，）
            this.manyTableData.forEach((item) => {
              if (ManyList.attrId == item.id) {
                item.checkedCities = ManyList.attrVals
              }
            })
          })
        }

        console.log(this.manyTableData)
      } else if (this.activeIndex === '2') {
        const { data: res } = await this.$http.get(
          `api/service-product/admin/product/attribute/${this.cateId}`,
          {
            params: { attrSel: 'only' },
          }
        )
        if (res.code !== 200) {
          return this.$message.error('获取静态属性列表失败')
        }
        // console.log(res.data)
        this.onlyTableData = res.data
      }
    },

    //处理图片预览效果事件 file是函数自带
    handlePreview(file) {
      console.log(file)
      //绑定图片地址
      this.previewPath = file.url
      // console.log(this.previewPath)
      //打开对话框
      this.previewVisible = true
    },

    //处理移除图片的操作
    handleRemove(file) {
      // console.log(file)
      //1.获取将要删除的图片的临时路径
      const id = file.pictureId

      if (this.$route.name === 'editProduct') {
        //2.从pics数组中，找到这个图片对应的索引值,findIndex()获取索引值
        const i = this.editForm.productPic.findIndex((x) => x.pictureId === id)
        //3.调用数组的splice方法 i 数组索引，1 代表删除一条记录，把图片信息对象，从pics数组中移除
        this.editForm.productPic.splice(i, 1)
        // console.log(this.editForm.productPic)
      } else {
        //2.从pics数组中，找到这个图片对应的索引值,findIndex()获取索引值
        const i = this.addForm.productPic.findIndex((x) => x.pictureId === id)
        //3.调用数组的splice方法 i 数组索引，1 代表删除一条记录，把图片信息对象，从pics数组中移除
        this.addForm.productPic.splice(i, 1)
      }
      // console.log(this.addForm)
    },

    //监听图片上传成功的事件
    handleSuccess(response) {
      // console.log(response)
      //1.拼接得到一个图片信息对象productPic
      const picInfo = {
        pictureId: response.data.data.id,
        url: 'http://8.134.34.190/' + response.data.data.fileIndex,
        name: response.data.data.fileName,
      }
      //如果是编辑商品操作
      if (this.$route.name === 'editProduct') {
        console.log(this.editForm)
        this.editForm.productPic.push(picInfo)
      } else {
        this.addForm.productPic.push(picInfo)
      }
      this.$message.success('上传文件成功！')
      // console.log(this.addForm)
    },
    //上传失败的事件
    handleError(error) {
      this.$message.error('上传文件失败！')
    },

    //添加商品
    add() {
      // console.log(this.addForm)
      this.$refs.addFormRef.validate(async (valid) => {
        if (!valid) {
          return this.$message.error('请填写必要的表单项')
        }
        //执行添加的业务逻辑
        //lodash  cloneDeep（obj）
        //拷贝对象（使用原因，因为级联选择器中的v-model绑定必须为数组，而后台接收要是字符串，故无法满足）
        const form = _.cloneDeep(this.addForm)
        form.categoryId = this.cateId

        // console.log(this.checkedCities)
        //处理动态参数
        this.manyTableData.forEach((item) => {
          const newInfo = {
            attrId: item.id,
            attrVals: item.checkedCities.join(' '),
            attrSel: item.attrSel,
          }
          this.addForm.productAttr.push(newInfo)
        })
        //处理静态属性
        this.onlyTableData.forEach((item) => {
          const newInfo = {
            attrId: item.id,
            attrVals: item.attrVals,
            attrSel: item.attrSel,
          }
          this.addForm.productAttr.push(newInfo)
        })
        //赋值给form
        form.productAttr = this.addForm.productAttr
        //将图片数组通过,拼接为字符串
        // console.log(form)
        //处理图片路径问题（防止暴露服务器ip）
        form.productPic.forEach((item) => {
          const str = item.url.split('/')
          item.url = str[3] + '/' + str[4]
        })

        //发起请求添加商品
        //商品的名称，必须是唯一的
        const { data: res } = await this.$http.post(
          'api/service-product/admin/product/add',
          form
        )
        if (res.code !== 200) {
          return this.$message.error('添加商品失败')
        }
        this.$message.success('添加商品成功!')
        this.$router.push('/productList')
        window.sessionStorage.setItem('activePath', '/productList')
      })
    },

    //修改商品信息并提交
    edit() {
      this.$refs.editFormRef.validate(async (valid) => {
        if (!valid) return
        //执行添加的业务逻辑
        //lodash  cloneDeep（obj）
        //拷贝对象（使用原因，因为级联选择器中的v-model绑定必须为数组，而后台接收要是字符串，故无法满足）
        const form1 = _.cloneDeep(this.editForm)
        form1.categoryId = this.cateId

        //处理动态参数
        let manyDataList = []
        this.manyTableData.forEach((item) => {
          const newInfo = {
            attrId: item.id,
            attrVals: item.checkedCities.join(' '),
            attrSel: item.attrSel,
          }
          manyDataList.push(newInfo)
        })

        //处理静态属性
        this.onlyTableData.forEach((item) => {
          const newInfo = {
            attrId: item.id,
            attrVals: item.attrVals,
            attrSel: item.attrSel,
          }
          manyDataList.push(newInfo)
        })
        this.editForm.productAttr = manyDataList
        //赋值给form
        form1.productAttr = this.editForm.productAttr
        //处理图片路径问题（防止暴露服务器ip）
        form1.productPic.forEach((item) => {
          const str = item.url.split('/')
          item.url = str[3] + '/' + str[4]
        })
        // console.log(form1)
        //发起修改菜单信息的数据请求
        const { data: res } = await this.$http.put(
          'api/service-product/admin/product/update',
          form1
        )
        if (res.code !== 200) {
          return this.$message.error(res.msg)
        }
        this.$router.push('/productList')
        window.sessionStorage.setItem('activePath', '/productList')
        //提示修改成功
        this.$message.success('更新商品成功！')
      })
    },
    //上传服务器
    submitUpload() {
      this.$refs.upload.submit()
    },

    //下一步
    next() {
      //判断当前的分类是否选中三级分类
      const flag = this.beforeTabLeave(null, '0')
      //选中则跳到下一个页面
      if (flag) {
        let i = Number(this.activeIndex)
        this.activeIndex = String(i + 1)
        this.tabClicked()
      }
    },

    //上一步
    step() {
      let i = Number(this.activeIndex)
      this.activeIndex = String(i - 1)
    },
  },

  //计算属性
  computed: {
    cateId() {
      if (this.$route.name === 'editProduct') {
        if (this.editForm.categoryId) {
          if (this.editForm.categoryId.length === 3) {
            return this.editForm.categoryId[2]
          }
        }
      } else {
        if (this.addForm.categoryId.length === 3) {
          return this.addForm.categoryId[2]
        }
      }
      return null
    },
  },
}
</script>

<style lang="less" scoped>
.el-steps {
  margin: 10px;
}
.el-form-item {
  margin-bottom: 20px;
}
.el-form-item /deep/ .el-form-item__label {
  padding: 0 10px 0 0 !important;
}
.el-checkbox {
  margin: 0 10px 0 0 !important;
}
.previewTmg {
  width: 100%;
}

.btnAdd {
  margin-top: 15px;
}
.el-card {
  width: 1290px;
}
</style>